var MessageMap = {
    // req_check_version 1 检查版本
    1: () => {
        let tb = {
            version: 0,
            getMsgID: function () {
                return 1;
            },
            encode: function (buf) {
                int32ToByte(tb.version, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                tb.version = ByteToint32(buf, startIndex);
                startIndex += 4;
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(1, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_notify_check_version 6 版本检查返回
    6: () => {
        let tb = {
            result: 0,
            curtime: stime(),
            getMsgID: function () {
                return 6;
            },
            encode: function (buf) {
                int32ToByte(tb.result, buf);
                tb.curtime.encode(buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                tb.result = ByteToint32(buf, startIndex);
                startIndex += 4;
                startIndex += tb.curtime.decode(buf, startIndex);
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(6, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_notify_heartbeat 18  心跳
    18: () => {
        let tb = {
            getMsgID: function () {
                return 18;
            },
            encode: function (_buf) {
            },
            decode: function (_buf, index) {
                let startIndex = index;
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(18, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_req_login 659 登录
    659: () => {
        let tb = {
            login_type: 0,
            username: '',
            password: '',
            device_id: '',
            debug: '',
            device_model: '',
            app_version: '',
            channel_id: 0,
            aaa: '',
            bbb: '',
            ip: '',
            captcha: '',
            getMsgID: function () {
                return 659;
            },
            encode: function (buf) {
                int32ToByte(tb.login_type, buf);
                utf8StrtoBytes(tb.username, buf);
                utf8StrtoBytes(tb.password, buf);
                utf8StrtoBytes(tb.device_id, buf);
                utf8StrtoBytes(tb.debug, buf);
                utf8StrtoBytes(tb.device_model, buf);
                utf8StrtoBytes(tb.app_version, buf);
                int32ToByte(tb.channel_id, buf);
                utf8StrtoBytes(tb.aaa, buf);
                utf8StrtoBytes(tb.bbb, buf);
                utf8StrtoBytes(tb.ip, buf);
                utf8StrtoBytes(tb.captcha, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                tb.login_type = ByteToint32(buf, startIndex);
                startIndex += 4;
                let username_value = byteToString(buf, startIndex);
                tb.username = username_value[0];
                startIndex += username_value[1];
                let password_value = byteToString(buf, startIndex);
                tb.password = password_value[0];
                startIndex += password_value[1];
                let device_id_value = byteToString(buf, startIndex);
                tb.device_id = device_id_value[0];
                startIndex += device_id_value[1];
                let debug_value = byteToString(buf, startIndex);
                tb.debug = debug_value[0];
                startIndex += debug_value[1];
                let device_model_value = byteToString(buf, startIndex);
                tb.device_model = device_model_value[0];
                startIndex += device_model_value[1];
                let app_version_value = byteToString(buf, startIndex);
                tb.app_version = app_version_value[0];
                startIndex += app_version_value[1];
                tb.channel_id = ByteToint32(buf, startIndex);
                startIndex += 4;
                let aaa_value = byteToString(buf, startIndex);
                tb.aaa = aaa_value[0];
                startIndex += aaa_value[1];
                let bbb_value = byteToString(buf, startIndex);
                tb.bbb = bbb_value[0];
                startIndex += bbb_value[1];
                let ip_value = byteToString(buf, startIndex);
                tb.ip = ip_value[0];
                startIndex += ip_value[1];
                let captcha_value = byteToString(buf, startIndex);
                tb.captcha = captcha_value[0];
                startIndex += captcha_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(659, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_nodify_login 660 登录返回
    660: () => {
        let tb = {
            code: 0,
            message: '',
            user_id: 0,
            token: '',
            account_type: 0,
            is_default_bankpwd: 0,
            tokenid: '',
            newguidestate: 0,
            ipGroupName: '',
            getMsgID: function () {
                return 660;
            },
            encode: function (buf) {
                int32ToByte(tb.code, buf);
                utf8StrtoBytes(tb.message, buf);
                int64ToByte(tb.user_id, buf);
                utf8StrtoBytes(tb.token, buf);
                int32ToByte(tb.account_type, buf);
                int32ToByte(tb.is_default_bankpwd, buf);
                utf8StrtoBytes(tb.tokenid, buf);
                int32ToByte(tb.newguidestate, buf);
                utf8StrtoBytes(tb.ipGroupName, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                tb.code = ByteToint32(buf, startIndex);
                startIndex += 4;
                let message_value = byteToString(buf, startIndex);
                tb.message = message_value[0];
                startIndex += message_value[1];
                tb.user_id = ByteToint64(buf, startIndex);
                startIndex += 8;
                let token_value = byteToString(buf, startIndex);
                tb.token = token_value[0];
                startIndex += token_value[1];
                tb.account_type = ByteToint32(buf, startIndex);
                startIndex += 4;
                tb.is_default_bankpwd = ByteToint32(buf, startIndex);
                startIndex += 4;
                let tokenid_value = byteToString(buf, startIndex);
                tb.tokenid = tokenid_value[0];
                startIndex += tokenid_value[1];
                tb.newguidestate = ByteToint32(buf, startIndex);
                startIndex += 4;
                let ipGroupName_value = byteToString(buf, startIndex);
                tb.ipGroupName = ipGroupName_value[0];
                startIndex += ipGroupName_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(660, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_req_register_account 788 注册
    788: () => {
        let tb = {
            username: '',
            password: '',
            register_type: 0,
            sign: '',
            ip: '',
            ip_error: '',
            device_model: '',
            channel_id: 0,
            agent_id: 0,
            aaa: '',
            bbb: '',
            captcha: '',
            currency: 0,
            from_url: '',
            getMsgID: function () {
                return 788;
            },
            encode: function (buf) {
                utf8StrtoBytes(tb.username, buf);
                utf8StrtoBytes(tb.password, buf);
                int32ToByte(tb.register_type, buf);
                utf8StrtoBytes(tb.sign, buf);
                utf8StrtoBytes(tb.ip, buf);
                utf8StrtoBytes(tb.ip_error, buf);
                utf8StrtoBytes(tb.device_model, buf);
                int32ToByte(tb.channel_id, buf);
                int32ToByte(tb.agent_id, buf);
                utf8StrtoBytes(tb.aaa, buf);
                utf8StrtoBytes(tb.bbb, buf);
                utf8StrtoBytes(tb.captcha, buf);
                int32ToByte(tb.currency, buf);
                utf8StrtoBytes(tb.from_url, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                let username_value = byteToString(buf, startIndex);
                tb.username = username_value[0];
                startIndex += username_value[1];
                let password_value = byteToString(buf, startIndex);
                tb.password = password_value[0];
                startIndex += password_value[1];
                tb.register_type = ByteToint32(buf, startIndex);
                startIndex += 4;
                let sign_value = byteToString(buf, startIndex);
                tb.sign = sign_value[0];
                startIndex += sign_value[1];
                let ip_value = byteToString(buf, startIndex);
                tb.ip = ip_value[0];
                startIndex += ip_value[1];
                let ip_error_value = byteToString(buf, startIndex);
                tb.ip_error = ip_error_value[0];
                startIndex += ip_error_value[1];
                let device_model_value = byteToString(buf, startIndex);
                tb.device_model = device_model_value[0];
                startIndex += device_model_value[1];
                tb.channel_id = ByteToint32(buf, startIndex);
                startIndex += 4;
                tb.agent_id = ByteToint32(buf, startIndex);
                startIndex += 4;
                let aaa_value = byteToString(buf, startIndex);
                tb.aaa = aaa_value[0];
                startIndex += aaa_value[1];
                let bbb_value = byteToString(buf, startIndex);
                tb.bbb = bbb_value[0];
                startIndex += bbb_value[1];
                let captcha_value = byteToString(buf, startIndex);
                tb.captcha = captcha_value[0];
                startIndex += captcha_value[1];
                tb.currency = ByteToint32(buf, startIndex);
                startIndex += 4;
                let from_url_value = byteToString(buf, startIndex);
                tb.from_url = from_url_value[0];
                startIndex += from_url_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(788, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_notify_register_account 789 注册返回
    789: () => {
        let tb = {
            code: 0,
            message: '',
            getMsgID: function () {
                return 789;
            },
            encode: function (buf) {
                int32ToByte(tb.code, buf);
                utf8StrtoBytes(tb.message, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                tb.code = ByteToint32(buf, startIndex);
                startIndex += 4;
                let message_value = byteToString(buf, startIndex);
                tb.message = message_value[0];
                startIndex += message_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(789, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_req_register_captcha 794 验证码
    794: () => {
        let tb = {
            sign: '',
            aaa: '',
            bbb: '',
            getMsgID: function () {
                return 794;
            },
            encode: function (buf) {
                utf8StrtoBytes(tb.sign, buf);
                utf8StrtoBytes(tb.aaa, buf);
                utf8StrtoBytes(tb.bbb, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                let sign_value = byteToString(buf, startIndex);
                tb.sign = sign_value[0];
                startIndex += sign_value[1];
                let aaa_value = byteToString(buf, startIndex);
                tb.aaa = aaa_value[0];
                startIndex += aaa_value[1];
                let bbb_value = byteToString(buf, startIndex);
                tb.bbb = bbb_value[0];
                startIndex += bbb_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(794, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    },
    // msg_notify_register_captcha 795 验证码图片返回
    795: () => {
        let tb = {
            url: '',
            getMsgID: function () {
                return 795;
            },
            encode: function (buf) {
                utf8StrtoBytes(tb.url, buf);
            },
            decode: function (buf, index) {
                let startIndex = index;
                let url_value = byteToString(buf, startIndex);
                tb.url = url_value[0];
                startIndex += url_value[1];
                return startIndex - index;
            },
            build: function (buf) {
                uInt16ToByte(795, buf);
                return tb.encode(buf);
            }
        };
        return tb;
    }
}



var bigEndian = IsbigEndian()
function IsbigEndian() {
    var buffer = new ArrayBuffer(2);
    new DataView(buffer).setInt16(0, 256, true);
    return new Int16Array(buffer)[1] === 256;
}










//utf8字符串转字节数组
function utf8StrtoBytes(text, buf) {
    var i = 0;
    text = encodeURI(text);

    //先计算出字符串的长度
    let textLen = 0;
    while (i < text.length) {
        var c = text.charCodeAt(i++);
        // if it is a % sign, encode the following 2 bytes as a hex value
        if (c === 37) {
            i += 2;
            textLen++;
            // otherwise, just the actual byte
        } else {
            textLen++;
        }
    }

    uInt16ToByte(textLen, buf); //先把字符串的长度编码

    i = 0;
    while (i < text.length) {
        var c = text.charCodeAt(i++);

        // if it is a % sign, encode the following 2 bytes as a hex value
        if (c === 37) {
            buf.push(parseInt(text.substr(i, 2), 16));
            i += 2;
            // otherwise, just the actual byte
        } else {
            buf.push(c);
        }
    }
}

function decode_msg_total_length(buf, index) {
    let value =
        ((buf[index] & 0xff) << 24) |
        ((buf[index + 1] & 0xff) << 16) |
        ((buf[index + 2] & 0xff) << 8) |
        (buf[index + 3] & 0xff);

    return value;
}


function encode_msg_total_length(i, buf) {
    buf.push(i & 0xff);
    buf.push((i >> 8) & 0xff);
    buf.push((i >> 16) & 0xff);
    buf.push((i >> 24) & 0xff);
}


function swab32_msg_total_length(x) {
    let ret =
        ((x & 0x000000ff) << 24) |
        ((x & 0x0000ff00) << 8) |
        ((x & 0x00ff0000) >> 8) |
        ((x & 0xff000000) >> 24);
    return ret;
}


function int32ToByte(i, buf) {
    if (bigEndian) {
        buf.push((i >> 24) & 0xff);
        buf.push((i >> 16) & 0xff);
        buf.push((i >> 8) & 0xff);
        buf.push(i & 0xff);
    } else {
        buf.push(i & 0xff);
        buf.push((i >> 8) & 0xff);
        buf.push((i >> 16) & 0xff);
        buf.push((i >> 24) & 0xff);
    }
}


function uInt16ToByte(s, buf) {
    if (bigEndian) {
        buf.push((s >> 8) & 0xff);
        buf.push(s & 0xff);
    } else {
        buf.push(s & 0xff);
        buf.push((s >> 8) & 0xff);
    }
}


function int8ToByte(u, buf) {
    buf.push(u & 0xff);
}



function ByteToint32(buf, index) {
    let value = 0;
    if (bigEndian) {
        value =
            ((buf[index] & 0xff) << 24) |
            ((buf[index + 1] & 0xff) << 16) |
            ((buf[index + 2] & 0xff) << 8) |
            (buf[index + 3] & 0xff);
    } else {
        value =
            (buf[index] & 0xff) |
            ((buf[index + 1] & 0xff) << 8) |
            ((buf[index + 2] & 0xff) << 16) |
            ((buf[index + 3] & 0xff) << 24);
    }
    return value;
}

function ByteTouInt32_minus(buf, index) {
    //此函数不对外，专门去掉是最高位的符号位
    let value = 0;
    if (bigEndian) {
        value =
            ((~buf[index] & 0xff) << 24) |
            ((~buf[index + 1] & 0xff) << 16) |
            ((~buf[index + 2] & 0xff) << 8) |
            (~buf[index + 3] & 0xff);
    } else {
        value =
            (~buf[index] & 0xff) |
            ((~buf[index + 1] & 0xff) << 8) |
            ((~buf[index + 2] & 0xff) << 16) |
            ((~buf[index + 3] & 0xff) << 24);
    }

    if (value > 2147483647 || value < 0) {
        return value + 4294967296;
    }

    return value;
}




function ByteToInt32_minus(buf, index) {
    let value = 0;
    if (bigEndian) {
        value =
            ((~buf[index] & 0xff) << 24) |
            ((~buf[index + 1] & 0xff) << 16) |
            ((~buf[index + 2] & 0xff) << 8) |
            (~buf[index + 3] & 0xff);
    } else {
        value =
            (~buf[index] & 0xff) |
            ((~buf[index + 1] & 0xff) << 8) |
            ((~buf[index + 2] & 0xff) << 16) |
            ((~buf[index + 3] & 0xff) << 24);
    }

    return value;
}



function ByteToUint16(buf, index) {
    let value = 0;
    if (bigEndian) {
        value = ((buf[index] & 0xff) << 8) | (buf[index + 1] & 0xff);
    } else {
        value = (buf[index] & 0xff) | ((buf[index + 1] & 0xff) << 8);
    }
    return value;
}



function ByteToint8(buf, index) {
    let value = buf[index] & 0xff;
    if (value > 127) {
        value -= 256;
    }
    return value;
}


function ByteTouInt8(buf, index) {
    return buf[index] & 0xff;
}


function hex2int(hex) {
    var len = hex.length,
        a = new Array(len),
        code;
    for (var i = 0; i < len; i++) {
        code = hex.charCodeAt(i);
        if (48 <= code && code < 58) {
            code -= 48;
        } else {
            code = (code & 0xdf) - 65 + 10;
        }
        a[i] = code;
    }

    return a.reduce(function (acc, c) {
        acc = 16 * acc + c;
        return acc;
    }, 0);
}




class RingBuffer {
    size = 0;
    list = [];
    // private capacity:number = 0;
    head = 0;
    tail = 0;

    constructor() {
        this.initQueue(4 * 1024 * 1024); //size必须是2的n次方
    }
    //初始化队列
    initQueue(size) {
        this.size = this.FixLength(size);
        this.list = new Array();
        // this.capacity = size + 1;
        this.head = 0;
        this.tail = 0;
    }

    FixLength(length) {
        var n = 2;
        var b = 2;
        while (b < length) {
            b = 2 << n;
            n++;
        }
        return b;
    }

    //压入队列
    Push(ele) {
        if (typeof ele == undefined || ele == null) {
            return;
        }

        if (this.list != null) {
            this.list[this.tail & (this.size - 1)] = ele;
            this.tail++;
        }
    }

    Pop() {
        if (this.tail == this.head || this.list == null) {
            return null;
        }

        return this.list[this.head++ & (this.size - 1)];
    }

    Pop2(index) {
        if (this.tail == this.head || this.list == null) {
            return null;
        }

        return this.list[(this.head + index) & (this.size - 1)];
    }

    DataLength() {
        return (this.tail - this.head) & (this.size - 1);
    }

    addHead(offset) {
        this.head += offset;
    }

    Clear() {
        this.head = 0;
        this.tail = 0;
    }

    decode_msg_total_length() {
        let bodyLen = decode_msg_total_length(this.list, this.head);
        return bodyLen;
    }

    decode_msg_id() {
        let msgID = ByteToUint16(this.list, this.head);
        this.addHead(2);
        return msgID;
    }

    decode_msg_body(message, bodyLen) {
        let tb = message();
        tb.decode(this.list, this.head);
        this.addHead(bodyLen);
        return tb;
    }
}



function md5(md5str) {
    var createMD5String = function (string) {
        var x = Array();
        var k, AA, BB, CC, DD, a, b, c, d;
        var S11 = 7,
            S12 = 12,
            S13 = 17,
            S14 = 22;
        var S21 = 5,
            S22 = 9,
            S23 = 14,
            S24 = 20;
        var S31 = 4,
            S32 = 11,
            S33 = 16,
            S34 = 23;
        var S41 = 6,
            S42 = 10,
            S43 = 15,
            S44 = 21;
        string = uTF8Encode(string);
        x = convertToWordArray(string);
        a = 0x67452301;
        b = 0xefcdab89;
        c = 0x98badcfe;
        d = 0x10325476;
        for (k = 0; k < x.length; k += 16) {
            AA = a;
            BB = b;
            CC = c;
            DD = d;
            a = FF(a, b, c, d, x[k + 0], S11, 0xd76aa478);
            d = FF(d, a, b, c, x[k + 1], S12, 0xe8c7b756);
            c = FF(c, d, a, b, x[k + 2], S13, 0x242070db);
            b = FF(b, c, d, a, x[k + 3], S14, 0xc1bdceee);
            a = FF(a, b, c, d, x[k + 4], S11, 0xf57c0faf);
            d = FF(d, a, b, c, x[k + 5], S12, 0x4787c62a);
            c = FF(c, d, a, b, x[k + 6], S13, 0xa8304613);
            b = FF(b, c, d, a, x[k + 7], S14, 0xfd469501);
            a = FF(a, b, c, d, x[k + 8], S11, 0x698098d8);
            d = FF(d, a, b, c, x[k + 9], S12, 0x8b44f7af);
            c = FF(c, d, a, b, x[k + 10], S13, 0xffff5bb1);
            b = FF(b, c, d, a, x[k + 11], S14, 0x895cd7be);
            a = FF(a, b, c, d, x[k + 12], S11, 0x6b901122);
            d = FF(d, a, b, c, x[k + 13], S12, 0xfd987193);
            c = FF(c, d, a, b, x[k + 14], S13, 0xa679438e);
            b = FF(b, c, d, a, x[k + 15], S14, 0x49b40821);
            a = GG(a, b, c, d, x[k + 1], S21, 0xf61e2562);
            d = GG(d, a, b, c, x[k + 6], S22, 0xc040b340);
            c = GG(c, d, a, b, x[k + 11], S23, 0x265e5a51);
            b = GG(b, c, d, a, x[k + 0], S24, 0xe9b6c7aa);
            a = GG(a, b, c, d, x[k + 5], S21, 0xd62f105d);
            d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
            c = GG(c, d, a, b, x[k + 15], S23, 0xd8a1e681);
            b = GG(b, c, d, a, x[k + 4], S24, 0xe7d3fbc8);
            a = GG(a, b, c, d, x[k + 9], S21, 0x21e1cde6);
            d = GG(d, a, b, c, x[k + 14], S22, 0xc33707d6);
            c = GG(c, d, a, b, x[k + 3], S23, 0xf4d50d87);
            b = GG(b, c, d, a, x[k + 8], S24, 0x455a14ed);
            a = GG(a, b, c, d, x[k + 13], S21, 0xa9e3e905);
            d = GG(d, a, b, c, x[k + 2], S22, 0xfcefa3f8);
            c = GG(c, d, a, b, x[k + 7], S23, 0x676f02d9);
            b = GG(b, c, d, a, x[k + 12], S24, 0x8d2a4c8a);
            a = HH(a, b, c, d, x[k + 5], S31, 0xfffa3942);
            d = HH(d, a, b, c, x[k + 8], S32, 0x8771f681);
            c = HH(c, d, a, b, x[k + 11], S33, 0x6d9d6122);
            b = HH(b, c, d, a, x[k + 14], S34, 0xfde5380c);
            a = HH(a, b, c, d, x[k + 1], S31, 0xa4beea44);
            d = HH(d, a, b, c, x[k + 4], S32, 0x4bdecfa9);
            c = HH(c, d, a, b, x[k + 7], S33, 0xf6bb4b60);
            b = HH(b, c, d, a, x[k + 10], S34, 0xbebfbc70);
            a = HH(a, b, c, d, x[k + 13], S31, 0x289b7ec6);
            d = HH(d, a, b, c, x[k + 0], S32, 0xeaa127fa);
            c = HH(c, d, a, b, x[k + 3], S33, 0xd4ef3085);
            b = HH(b, c, d, a, x[k + 6], S34, 0x4881d05);
            a = HH(a, b, c, d, x[k + 9], S31, 0xd9d4d039);
            d = HH(d, a, b, c, x[k + 12], S32, 0xe6db99e5);
            c = HH(c, d, a, b, x[k + 15], S33, 0x1fa27cf8);
            b = HH(b, c, d, a, x[k + 2], S34, 0xc4ac5665);
            a = II(a, b, c, d, x[k + 0], S41, 0xf4292244);
            d = II(d, a, b, c, x[k + 7], S42, 0x432aff97);
            c = II(c, d, a, b, x[k + 14], S43, 0xab9423a7);
            b = II(b, c, d, a, x[k + 5], S44, 0xfc93a039);
            a = II(a, b, c, d, x[k + 12], S41, 0x655b59c3);
            d = II(d, a, b, c, x[k + 3], S42, 0x8f0ccc92);
            c = II(c, d, a, b, x[k + 10], S43, 0xffeff47d);
            b = II(b, c, d, a, x[k + 1], S44, 0x85845dd1);
            a = II(a, b, c, d, x[k + 8], S41, 0x6fa87e4f);
            d = II(d, a, b, c, x[k + 15], S42, 0xfe2ce6e0);
            c = II(c, d, a, b, x[k + 6], S43, 0xa3014314);
            b = II(b, c, d, a, x[k + 13], S44, 0x4e0811a1);
            a = II(a, b, c, d, x[k + 4], S41, 0xf7537e82);
            d = II(d, a, b, c, x[k + 11], S42, 0xbd3af235);
            c = II(c, d, a, b, x[k + 2], S43, 0x2ad7d2bb);
            b = II(b, c, d, a, x[k + 9], S44, 0xeb86d391);
            a = addUnsigned(a, AA);
            b = addUnsigned(b, BB);
            c = addUnsigned(c, CC);
            d = addUnsigned(d, DD);
        }
        var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
        return tempValue.toLowerCase();
    };
    var rotateLeft = function (lValue, iShiftBits) {
        return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
    };
    var addUnsigned = function (lX, lY) {
        var lX4, lY4, lX8, lY8, lResult;
        lX8 = lX & 0x80000000;
        lY8 = lY & 0x80000000;
        lX4 = lX & 0x40000000;
        lY4 = lY & 0x40000000;
        lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff);
        if (lX4 & lY4) return lResult ^ 0x80000000 ^ lX8 ^ lY8;
        if (lX4 | lY4) {
            if (lResult & 0x40000000) return lResult ^ 0xc0000000 ^ lX8 ^ lY8;
            else return lResult ^ 0x40000000 ^ lX8 ^ lY8;
        } else {
            return lResult ^ lX8 ^ lY8;
        }
    };
    var F = function (x, y, z) {
        return (x & y) | (~x & z);
    };
    var G = function (x, y, z) {
        return (x & z) | (y & ~z);
    };
    var H = function (x, y, z) {
        return x ^ y ^ z;
    };
    var I = function (x, y, z) {
        return y ^ (x | ~z);
    };
    var FF = function (a, b, c, d, x, s, ac) {
        a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var GG = function (a, b, c, d, x, s, ac) {
        a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var HH = function (a, b, c, d, x, s, ac) {
        a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var II = function (a, b, c, d, x, s, ac) {
        a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var convertToWordArray = function (string) {
        var lWordCount;
        var lMessageLength = string.length;
        var lNumberOfWordsTempOne = lMessageLength + 8;
        var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
        var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
        var lWordArray = Array(lNumberOfWords - 1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while (lByteCount < lMessageLength) {
            lWordCount = (lByteCount - (lByteCount % 4)) / 4;
            lBytePosition = (lByteCount % 4) * 8;
            lWordArray[lWordCount] = lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition);
            lByteCount++;
        }
        lWordCount = (lByteCount - (lByteCount % 4)) / 4;
        lBytePosition = (lByteCount % 4) * 8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
        lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
        lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
        return lWordArray;
    };
    var wordToHex = function (lValue) {
        var WordToHexValue = "",
            WordToHexValueTemp = "",
            lByte,
            lCount;
        for (lCount = 0; lCount <= 3; lCount++) {
            lByte = (lValue >>> (lCount * 8)) & 255;
            WordToHexValueTemp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
        }
        return WordToHexValue;
    };
    var uTF8Encode = function (string) {
        string = string.toString().replace(/\x0d\x0a/g, "\x0a");
        var output = "";
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                output += String.fromCharCode(c);
            } else if (c > 127 && c < 2048) {
                output += String.fromCharCode((c >> 6) | 192);
                output += String.fromCharCode((c & 63) | 128);
            } else {
                output += String.fromCharCode((c >> 12) | 224);
                output += String.fromCharCode(((c >> 6) & 63) | 128);
                output += String.fromCharCode((c & 63) | 128);
            }
        }
        return output;
    };
    return createMD5String(md5str);
}


function getRandomSign(deviceId) {
    let random1 = getRandomNum(0, 9);
    let random2 = getRandomNum(0, 9);
    let baseStr =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let leng = baseStr.length;
    let str1 = '';
    for (let k = 0; k < random1; ++k) {
        let idx = getRandomNum(0, leng - 1);
        let tmp = baseStr[idx];
        str1 = str1 + tmp;
    }
    let str2 = '';
    for (let k = 0; k < random2; ++k) {
        let idx = getRandomNum(0, leng - 1);
        let tmp = baseStr[idx];
        str2 = str2 + tmp;
    }
    let str = random1.toString() + random2.toString() + str1 + deviceId + str2;
    let base64Str = btoa(str);

    return base64Str;
};

function getRandomNum(start, end) {
    return Math.round(Math.random() * (end - start) + start);
};


function getUuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (Math.random() * 16) | 0,
            v = c == 'x' ? r : (r & 0x3) | 0x8;
        return v.toString(16);
    });
}


function stime() {
    let tb = {
        year: 0,
        month: 0,
        day: 0,
        hour: 0,
        minute: 0,
        second: 0,
        getMsgID: function () {
            return 2;
        },
        encode: function (buf) {
            int32ToByte(tb.year, buf);
            int32ToByte(tb.month, buf);
            int32ToByte(tb.day, buf);
            int32ToByte(tb.hour, buf);
            int32ToByte(tb.minute, buf);
            int32ToByte(tb.second, buf);
        },
        decode: function (buf, index) {
            let startIndex = index;
            tb.year = ByteToint32(buf, startIndex);
            startIndex += 4;
            tb.month = ByteToint32(buf, startIndex);
            startIndex += 4;
            tb.day = ByteToint32(buf, startIndex);
            startIndex += 4;
            tb.hour = ByteToint32(buf, startIndex);
            startIndex += 4;
            tb.minute = ByteToint32(buf, startIndex);
            startIndex += 4;
            tb.second = ByteToint32(buf, startIndex);
            startIndex += 4;
            return startIndex - index;
        },
        build: function (buf) {
            uInt16ToByte(2, buf);
            return tb.encode(buf);
        }
    };
    return tb;
}


function byteToString(buf, index) {
    if (typeof buf === 'string') {
        return buf;
    }
    //先解字符串的长度
    let len = this.ByteToUint16(buf, index);

    var str = '',
        _arr = buf;
    let start = index + 2;
    let end = index + 2 + len;
    for (var i = start; i < end; i++) {
        if (i >= _arr.length) break; // todo这里会越界

        var one = _arr[i].toString(2),
            v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
            var bytesLength = v[0].length;
            var store = _arr[i].toString(2).slice(7 - bytesLength);
            for (var st = 1; st < bytesLength; st++) {
                store += _arr[st + i].toString(2).slice(2);
            }
            str += String.fromCharCode(parseInt(store, 2));
            i += bytesLength - 1;
        } else {
            str += String.fromCharCode(_arr[i]);
        }
    }
    return [str, len + 2]; //这里的4是字符串的长度，也编码进去了,固定4个字节
}



function int64ToByte(i, buf) {
    // if (!i) return
    let value = this.getHAndLBitFromNumber(i);
    let h = value[0];
    let l = value[1];
    if (bigEndian) {
        buf.push((h >> 24) & 0xff);
        buf.push((h >> 16) & 0xff);
        buf.push((h >> 8) & 0xff);
        buf.push(h & 0xff);

        buf.push((l >> 24) & 0xff);
        buf.push((l >> 16) & 0xff);
        buf.push((l >> 8) & 0xff);
        buf.push(l & 0xff);
    } else {
        buf.push(l & 0xff);
        buf.push((l >> 8) & 0xff);
        buf.push((l >> 16) & 0xff);
        buf.push((l >> 24) & 0xff);

        buf.push(h & 0xff);
        buf.push((h >> 8) & 0xff);
        buf.push((h >> 16) & 0xff);
        buf.push((h >> 24) & 0xff);
    }
}


function getHAndLBitFromNumber(num) {
    let h = 0;
    let l = 0;

    let hex_str = num.toString(16);
    let len = hex_str.length;
    if (num >= 0) {
        if (len > 8) {
            let l0 = hex_str.substring(len - 8, len);
            let h0 = hex_str.substring(0, len - 8);
            h = hex2int(h0);
            l = hex2int(l0);
        } else {
            l = num;
            h = 0;
        }
    } else {
        //符号位存在最高位
        if (len > 9) {
            let l0 = hex_str.substring(len - 8, len);
            let h0 = hex_str.substring(1, len - 8);
            h = hex2int(h0) | 0x80000000;
            l = hex2int(l0);
        } else {
            l = num * -1;
            h = 0x80000000;
        }
    }

    return [h, l];
}



function ByteToint64(buf, index) {
    let h = 0;
    let l = 0;
    let flag = 1;
    if (bigEndian) {
        if ((buf[index] & 0x80) > 0) {
            //最高位存的符号位
            //最高位>0，表示负数
            flag = -1;
            //高位采用int32来表示，
            //在js里面，最大整数只有2的53次方, 所以这里只支持-2的53次方--- 2的53次方
            h = ByteToInt32_minus(buf, index);
            //低位必须采用uint32来表示，因为低位不能带符号位
            l = ByteTouInt32_minus(buf, index + 4);
        } else {
            h = ByteToint32(buf, index);
            l = ByteTouInt32(buf, index + 4);
        }
    } else {
        if ((buf[index + 7] & 0x08) > 0) {
            //最高位存的符号位
            flag = -1;
            //高位采用int32来表示
            //在js里面，最大整数只有2的53次方, 所以这里只支持-2的53次方--- 2的53次方
            h = ByteToInt32_minus(buf, index + 4);
            //低位必须采用uint32来表示，因为低位不能带符号位
            l = ByteTouInt32_minus(buf, index);
        } else {
            h = ByteToint32(buf, index + 4);
            l = ByteTouInt32(buf, index);
        }
    }

    if (flag < 0) {
        return (getNumberFromHAndLBit(h, l) + 1) * -1;
    }
    return getNumberFromHAndLBit(h, l);
}

function ByteTouInt32(buf, index) {
    let value = ByteToint32(buf, index);
    if (value > 2147483647 || value < 0) {
        return value + 4294967296;
    }
    return value;
}



function getNumberFromHAndLBit(h, l) {
    let flag = 1;
    if (h < 0) {
        flag = -1;
        h = -h;
    }
    let h_str = h.toString(16);
    let l_str = l.toString(16);
    let len = l_str.length;
    if (len < 8) {
        for (let i = 0; i < 8 - len; i++) {
            l_str = '0' + l_str;
        }
    }

    return hex2int(h_str + l_str) * flag;
}